﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using WI.CandidateManager.Common.Data.Entities;
using WI.CandidateManager.Common.Data.Enums;

namespace WI.CandidateManager.Business.Objects
{
    public class SubjectBO:BOBase
    {
        #region DeleteAndGetSubjects

        /// <summary>
        /// Deletes the subject.
        /// </summary>
        /// <param name="subjectId">The subject id.</param>
        /// <returns></returns>
        public bool DeleteSubject(long subjectId)
        {
            try
            {
                Logger.Info("Try to delete subject");
                var subject = DataContext.SubjectSet.Single(s => s.Id == subjectId);
                foreach (var schedule in subject.Schedules)
                {
                    foreach (var occurrence in schedule.Occurrences)
                    {
                        new OccurrenceBO().DeleteOccurence(occurrence.Id);
                    }
                    new ScheduleBO().DeleteSchedule(schedule.SubjectId, schedule.StudyGroupId);
                }
                subject.State = State.Deleted;
                DataContext.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Can't delete subject (subjectId: {0})", subjectId), ex);
                return false;
            }
        }

        /// <summary>
        /// Gets the subjects.
        /// </summary>
        /// <param name="subjectId">The subject id.</param>
        /// <param name="coachId">The coach id.</param>
        /// <returns></returns>
        public IEnumerable<Subject> GetSubjects(long? subjectId = null, long? coachId = null)
        {
            return DataContext.SubjectSet
                .Where(s =>
                    (!subjectId.HasValue || s.Id == subjectId) &&
                    (s.State == State.Active) &&
                    (!coachId.HasValue || s.CoachId == coachId));
        }

        #endregion

        #region SaveSubject

        /// <summary>
        /// Saves the subject.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <returns></returns>
        public bool SaveSubject(Subject subject)
        {
            try
            {
                Logger.Info("Try to save subject");
                if (subject.Id > 0)
                {
                    Logger.Info("Try to update group by Coach");
                    ApplyChanges(subject);
                }
                else
                {
                    Logger.Info("Try to create subject by Coach");
                    subject.CoachId = Session.User.Id;
                    DataContext.SubjectSet.Add(subject);
                }
                DataContext.SaveChanges();
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error("Can't added subject", ex);
                return false;
            }
        }

        /// <summary>
        /// Applies the changes.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">subject</exception>
        /// <exception cref="System.InvalidOperationException">SubjectId must be setted before apply changes</exception>
        protected Subject ApplyChanges(Subject subject)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }
            if (subject.Id <= 0)
            {
                throw new InvalidOperationException("SubjectId must be setted before apply changes");
            }

            var updateSubject = DataContext.SubjectSet.Single(s => s.Id == subject.Id);
            updateSubject.Name = subject.Name;
            updateSubject.Description = subject.Description;
            updateSubject.State = subject.State;
            updateSubject.CoachId = Session.User.Id;
            DataContext.Entry(updateSubject).State = EntityState.Modified;
            return updateSubject;
        }

         #endregion
    }
}
